home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / daymisckit_proj / daymisckit-1 / DAYTime.m < prev    next >
Text File  |  1995-06-12  |  11KB  |  444 lines

  1. //
  2. //    DAYTime.m -- a generic class to simplify manipulation of times
  3. //        Written by Don Yacktman (c) 1993 by Don Yacktman.
  4. //                Version 1.0.  All rights reserved.
  5. //
  6. //        This is a free object!  Contact the author for the latest version.
  7. //        Don Yacktman, 4279 N. Ivy Lane, Provo, UT, 84604
  8. //        e-mail:  Don_Yacktman@byu.edu
  9. //
  10. //        You may use and copy this class freely as long as you
  11. //        comply with the following terms:
  12. //            (1) Do not remove the author's name or any of the
  13. //                copyright notices from this file.
  14. //            (2) If you redistribute an application which uses this
  15. //                object, you must either include the source code for
  16. //                this object with the application or state in your
  17. //                application's documentation that you (a) use this
  18. //                object and (b) where to obtain the source code for
  19. //                the object.
  20. //            (3) In no way shall the author or his employer(s) be held
  21. //                responsible for any damages caused by what this object
  22. //                does or does not do.
  23. //            (4) You have no warranty whatsoever that this object is
  24. //                good for any purpose at all.  If you find it useful
  25. //                for something, consider yourself lucky and leave it at that.
  26. //
  27.  
  28.     // *****  denotes an unfinished/unimplemented method.
  29.  
  30. #import <daymisckit/DAYTime.h>
  31. #import <sys/time.h>
  32.  
  33. // a few functions to handle date wierdnesses
  34.  
  35. int isLeapYear(int year)
  36. {
  37.     // *****
  38.     return 0;
  39. }
  40.  
  41. int DAY_daysUpTo(int month, int year)
  42. {
  43.     int array[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  44.     if (month < 2) return array[month];
  45.     return (array[month] + isLeapYear(year));
  46. }
  47.  
  48. int DAY_daysIn(int month, int year)
  49. {
  50.     int array[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  51.     if (month != 1) return array[month];
  52.     return (array[month] + isLeapYear(year));
  53. }
  54.  
  55. @implementation DAYTime
  56.  
  57. - init
  58. {
  59.     id ret;
  60.     if (!_initted) ret = [super init];
  61.     else ret = self;
  62.     _initted = YES;
  63.     dow = DAY_UNKNOWN_DOW;
  64.     if (!myStringValue) myStringValue = (char *)malloc(256);
  65.     year = 0; day = 0; month = 0; hour = 0;
  66.     minute = 0; second = 0; microsecond = 0;
  67.     isRelative = NO;
  68.     return ret;
  69. }
  70.  
  71. - initWithCurrentTime
  72. {
  73.     struct timeval tp;
  74.     struct timezone tzp;
  75.     struct tm *tv;
  76.     
  77.     id ret = [self init];
  78.  
  79.     gettimeofday(&tp, &tzp);
  80.     tv = localtime(&tp.tv_sec);
  81.     
  82.     microsecond = tp.tv_usec;
  83.     second = tv->tm_sec;
  84.     minute = tv->tm_min;
  85.     hour   = tv->tm_hour;
  86.     day    = tv->tm_mday - 1;
  87.     dow    = tv->tm_wday;
  88.     month  = tv->tm_mon;
  89.     year   = tv->tm_year;
  90.     return ret;
  91. }
  92.  
  93. - calcDayOfWeek
  94. {
  95.     // ***** 
  96.     return self;
  97. }
  98.  
  99. - setYear:(int)t { year = t; dow = DAY_UNKNOWN_DOW; return self; }
  100. - setMonth:(int)t { month = t; dow = DAY_UNKNOWN_DOW; return self; }
  101. - setDayOfWeek:(int)t { dow = t; return self; }
  102. - setDay:(int)t { day = t; dow = DAY_UNKNOWN_DOW; return self; }
  103. - setHour:(int)t { hour = t; return self; }
  104. - setMinute:(int)t { minute = t; return self; }
  105. - setSecond:(int)t { second = t; return self; }
  106. - setMicrosecond:(int)t { microsecond = t; return self; }
  107. - setRelative:(BOOL)t { isRelative = t; return self; }
  108.  
  109. - (int)_nintValue // ignores usecs.
  110. {    // ***** Not quite right; ignores leap years
  111.     return ((((((year - 1970) * DAY_MAX_DAYS
  112.                 + DAY_daysUpTo(month, year) + day)
  113.                 * DAY_MAX_HOURS) + hour)
  114.                 * DAY_MAX_MINUTES + minute)
  115.                 * DAY_MAX_SECONDS + second);
  116. }
  117.  
  118. - (int)intValue // # seconds since Jan 1, 1970
  119. { // rounds usec. and add in...
  120.     return ([self _nintValue] +
  121.                 ((microsecond < DAY_MAX_MICROSECONDS / 2) ? 0 : 1));
  122. }
  123.  
  124. - (double)doubleValue
  125. {
  126.     // *****
  127.     return 0.0;
  128. }
  129.  
  130. - (float)floatValue
  131. {
  132.     // *****
  133.     return 0.0;
  134. }
  135.  
  136. - (const char *)stringValue
  137. { // Need to allow the user to set the time and/or date format! *****
  138.     // Don't free this!  that's why it's a const!
  139.     if (!myStringValue) myStringValue = (char *)malloc(256);
  140.     sprintf(myStringValue, "%ld : %ld : %ld", hour, minute, second);
  141.     return myStringValue;
  142. }
  143.  
  144. - free
  145. {
  146.     free(myStringValue);
  147.     return [super free];
  148. }
  149.  
  150. - (int)dayOfWeek
  151. {
  152.     if (dow < 0) [self calcDayOfWeek];
  153.     return dow;
  154. }
  155.  
  156. - (int)year { return year; }
  157. - (int)month { return month; }
  158. - (int)day { return day; }
  159. - (int)hour { return hour; }
  160. - (int)minute { return minute; }
  161. - (int)second { return second; }
  162. - (int)microsecond { return microsecond; }
  163. - (BOOL)isRelative { return isRelative; }
  164.  
  165.  
  166. - addTime:aTime
  167. {
  168.     if (![aTime isKindOf:[DAYTime class]]) return nil;
  169.     [self addMicroseconds:[aTime microsecond]];
  170.     [self addSeconds:[aTime second]];
  171.     [self addMinutes:[aTime minute]];
  172.     [self addHours:[aTime hour]];
  173.     [self addDays:[aTime day]];
  174.     [self addMonths:[aTime month]];
  175.     [self addYears:[aTime year]];
  176.     return self;
  177. }
  178.  
  179. - subtractTime:aTime
  180. {
  181.     if (![aTime isKindOf:[DAYTime class]]) return nil;
  182.     [self subtractMicroseconds:[aTime microsecond]];
  183.     [self subtractSeconds:[aTime second]];
  184.     [self subtractMinutes:[aTime minute]];
  185.     [self subtractHours:[aTime hour]];
  186.     [self subtractDays:[aTime day]];
  187.     [self subtractMonths:[aTime month]];
  188.     [self subtractYears:[aTime year]];
  189.     return self;
  190. }
  191.  
  192. - addMicroseconds:(long)t
  193. {
  194.     long x = [self microsecond] + t;
  195.     if (!t) return self;
  196.     [self setMicrosecond:(x % DAY_MAX_MICROSECONDS)];
  197.     [self addSeconds:(x / DAY_MAX_MICROSECONDS)];
  198.     return self;
  199. }
  200.  
  201. - addSeconds:(long)t
  202. {
  203.     long x = [self second] + t;
  204.     if (!t) return self;
  205.     [self setSecond:(x % DAY_MAX_SECONDS)];
  206.     [self addMinutes:(x / DAY_MAX_SECONDS)];
  207.     return self;
  208. }
  209.  
  210. - addMinutes:(long)t
  211. {
  212.     long x = [self minute] + t;
  213.     if (!t) return self;
  214.     [self setMinute:(x % DAY_MAX_MINUTES)];
  215.     [self addHours:(x / DAY_MAX_MINUTES)];
  216.     return self;
  217. }
  218.  
  219. - addHours:(long)t
  220. {
  221.     long x = [self hour] + t;
  222.     if (!t) return self;
  223.     [self setHour:(x % DAY_MAX_HOURS)];
  224.     [self addDays:(x / DAY_MAX_HOURS)];
  225.     return self;
  226. }
  227.  
  228. - addDays:(long)t
  229. {
  230.     long x = [self day] + t; int k;
  231.     if (!t) return self;
  232.     
  233.     k = DAY_daysIn(month, year);
  234.     while (x >= k) { // This is slow, but it works.
  235.         [self addMonths:1];
  236.         x -= k; k = DAY_daysIn(month, year);
  237.     }
  238.     [self setDay:(x % DAY_MAX_DAYS)];
  239.     return self;
  240. }
  241.  
  242. - addWeeks:(long)t
  243. {
  244.     return [self addDays:(t * 7)];
  245. }
  246.  
  247. - addMonths:(long)t
  248. {
  249.     long x = [self month] + t;
  250.     if (!t) return self;
  251.     [self setMonth:(x % DAY_MAX_MONTHS)];
  252.     [self addYears:(x / DAY_MAX_MONTHS)];
  253.     return self;
  254. }
  255.  
  256. - addYears:(long)t
  257. {
  258.     if (t) [self setYear:([self year] + t)];
  259.     return self;
  260. }
  261.  
  262. - (BOOL)isAfter:aTime
  263. { // returns YES if we are "older" than time passed in
  264.     int si = [self _nintValue];
  265.     int oi = [aTime _nintValue];
  266.     if (si > oi) return YES;
  267.     if ((si == oi) && ([self microsecond] > [aTime microsecond])) return YES;
  268.     return NO;
  269. }
  270.  
  271. - (BOOL)isEqual:aTime
  272. { // returns YES if we are "same" as time passed in
  273.     if (([self _nintValue] == [aTime _nintValue]) &&
  274.             ([self microsecond] == [aTime microsecond])) return YES;
  275.     return NO;
  276. }
  277.  
  278. - subtractMicroseconds:(long)t
  279. {
  280.     long us = t % DAY_MAX_MICROSECONDS;
  281.     long s = t / DAY_MAX_MICROSECONDS;
  282.     long sus = [self microsecond];
  283.     if (us > sus) { s++; sus += DAY_MAX_MICROSECONDS; }
  284.     [self subtractSeconds:s];
  285.     [self setMicrosecond:(sus - us)];
  286.     return self;
  287. }
  288.  
  289. - subtractSeconds:(long)t
  290. {
  291.     long s = t % DAY_MAX_SECONDS;
  292.     long m = t / DAY_MAX_SECONDS;
  293.     long ss = [self second];
  294.     if (s > ss) { m++; ss += DAY_MAX_SECONDS; }
  295.     [self subtractMinutes:m];
  296.     [self setSecond:(ss - s)];
  297.     return self;
  298. }
  299.  
  300. - subtractMinutes:(long)t
  301. {
  302.     long m = t % DAY_MAX_MINUTES;
  303.     long h = t / DAY_MAX_MINUTES;
  304.     long sm = [self minute];
  305.     if (m > sm) { h++; sm += DAY_MAX_MINUTES; }
  306.     [self subtractHours:h];
  307.     [self setMinute:(sm - m)];
  308.     return self;
  309. }
  310.  
  311. - subtractHours:(long)t
  312. {
  313.     long h = t % DAY_MAX_HOURS;
  314.     long d = t / DAY_MAX_HOURS;
  315.     long sh = [self hour];
  316.     if (h > sh) { d++; sh += DAY_MAX_HOURS; }
  317.     [self subtractDays:d];
  318.     [self setHour:(sh - h)];
  319.     return self;
  320. }
  321.  
  322. - subtractDays:(long)t
  323. {
  324.     long sd = [self day];
  325.     while (t > sd) { // this is slow, but it works.
  326.         sd += DAY_daysIn(month, year);
  327.         [self subtractMonths:1];
  328.     }
  329.     [self setDay:(sd - t)];
  330.     return self;
  331. }
  332.  
  333. - subtractWeeks:(long)t
  334. {
  335.     return [self subtractDays:(t * 7)];
  336. }
  337.  
  338. - subtractMonths:(long)t
  339. {
  340.     long m = t % DAY_MAX_MONTHS;
  341.     long y = t / DAY_MAX_MONTHS;
  342.     long sm = [self month];
  343.     if (m > sm) { y++; sm += DAY_MAX_MONTHS; }
  344.     [self subtractYears:y];
  345.     [self setMonth:(sm - m)];
  346.     return self;
  347. }
  348.  
  349. - subtractYears:(long)t
  350. {
  351.     if (t) [self setYear:([self year] - t)];
  352.     return self;
  353. }
  354.  
  355. - copy
  356. {
  357.     id myCopy = [[DAYTime alloc] init];
  358.     [myCopy setYear:year];
  359.     [myCopy setMonth:month];
  360.     [myCopy setDay:day];
  361.     [myCopy setDayOfWeek:dow];
  362.     [myCopy setHour:hour];
  363.     [myCopy setMinute:minute];
  364.     [myCopy setSecond:second];
  365.     [myCopy setMicrosecond:microsecond];
  366.     [myCopy setRelative:isRelative];
  367.     return myCopy;
  368. }
  369.  
  370. - copyTimeFrom:aTime
  371. {
  372.     [self setYear:[aTime year]];
  373.     [self setMonth:[aTime month]];
  374.     [self setDay:[aTime day]];
  375.     [self setDayOfWeek:[aTime dayOfWeek]];
  376.     [self setHour:[aTime hour]];
  377.     [self setMinute:[aTime minute]];
  378.     [self setSecond:[aTime second]];
  379.     [self setMicrosecond:[aTime microsecond]];
  380.     [self setRelative:[aTime isRelative]];
  381.     return self;
  382. }
  383.  
  384. - read:(NXTypedStream *)stream
  385. {
  386.     [super read:stream];
  387.     NXReadTypes(stream, "cllllllll", &isRelative, µsecond, &second,
  388.             &minute, &hour, &dow, &day, &month, &year);
  389.     if (!myStringValue) myStringValue = (char *)malloc(256);
  390.     return self;
  391. }
  392.  
  393. - write:(NXTypedStream *)stream
  394. {
  395.     [super write:stream];
  396.     NXWriteTypes(stream, "cllllllll", &isRelative, µsecond, &second,
  397.             &minute, &hour, &dow, &day, &month, &year);
  398.     return self;
  399. }
  400.  
  401. // NXTransport protocol implementation:
  402. - encodeUsing:(id <NXEncoding>)portal
  403. {
  404.     [portal encodeData:&isRelative  ofType:"c"];
  405.     [portal encodeData:µsecond ofType:"i"];
  406.     [portal encodeData:&second      ofType:"i"];
  407.     [portal encodeData:&minute      ofType:"i"];
  408.     [portal encodeData:&hour        ofType:"i"];
  409.     [portal encodeData:&dow         ofType:"i"];
  410.     [portal encodeData:&day         ofType:"i"];
  411.     [portal encodeData:&month       ofType:"i"];
  412.     [portal encodeData:&year        ofType:"i"];
  413.     return self;
  414. }
  415.  
  416. - decodeUsing:(id <NXDecoding>)portal
  417. {
  418.     [portal decodeData:&isRelative  ofType:"c"];
  419.     [portal decodeData:µsecond ofType:"i"];
  420.     [portal decodeData:&second      ofType:"i"];
  421.     [portal decodeData:&minute      ofType:"i"];
  422.     [portal decodeData:&hour        ofType:"i"];
  423.     [portal decodeData:&dow         ofType:"i"];
  424.     [portal decodeData:&day         ofType:"i"];
  425.     [portal decodeData:&month       ofType:"i"];
  426.     [portal decodeData:&year        ofType:"i"];
  427.     return self;
  428. }
  429.  
  430. - encodeRemotelyFor:(NXConnection *)connection
  431.     freeAfterEncoding:(BOOL *)flagp isBycopy:(BOOL)isByCopy
  432. {
  433.     if (isByCopy) {
  434.         *flagp = NO; // object will copy.
  435.         return self; //encode object (copy it)
  436.     }
  437.     *flagp = NO; // object will copy.
  438.     // super will encode the proxy otherwise
  439.     return [super encodeRemotelyFor:connection
  440.                 freeAfterEncoding:flagp isBycopy:isByCopy];
  441. }
  442.  
  443. @end
  444.